/*******************************************************************************
 * Copyright (c) 2008, 2009 Fabio Mauro - Alberto Terraneo.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.2
 * or any later version published by the Free Software Foundation.
 *     
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied 
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Free Documentation License for more details.
 *     
 * You should have received a copy of the GNU Free Documentation 
 * License along with this distribution; if not, send a email to authors:
 * aterraneo <at> users.sourceforge.net
 * bigmoby09 <at> users.sourceforge.net
 *******************************************************************************/
package it.blueocean.acanto.model;

import it.blueocean.acanto.model.common.ABaseEntity;
import it.blueocean.acanto.model.constants.StatoFamiglia;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Type;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name = "TA_FAMIGLIE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Famiglia extends ABaseEntity implements UserDetails
{
	private static final long serialVersionUID = 4521192060211479610L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "ID_FAMIGLIA", unique = true, nullable = false)
	private long id;

	@Column(name = "CDG", unique = true, length = 255, nullable = false)
	private String cdg;

	@Column(name = "PASSWORD", length = 45, nullable = false)
	private String password;

	@Column(name = "COGNOME_REFERENTE", length = 50)
	private String cognomeReferente;

	@Column(name = "NOME_REFERENTE", length = 50)
	private String nomeReferente;

	@Column(name = "NOTE")
	private String note;

	@Column(name = "ASSENTE_DAL", nullable = true)
	@Temporal(TemporalType.DATE)
	private Date assenteDal;

	@Column(name = "ASSENTE_AL", nullable = true)
	@Temporal(TemporalType.DATE)
	private Date assenteAl;

	@Column(name = "STATUS", columnDefinition = "CHAR(40)")
	@Enumerated(EnumType.STRING)
	private StatoFamiglia status;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "ID_GRUPPO")
	@ForeignKey(name = "FK_FAMIGLIA_GRUPPO")
	private Gruppo gruppo;

	@Column(name = "ENABLED", length = 1, nullable = false)
	@Type(type = "org.hibernate.type.TrueFalseType")
	private boolean enabled;

	@Column(name = "AUTHORIZATION_ROLE")
	private String authorizationRole;
	
	@Transient
	private String labelValue; // not persisted attribute

	public Famiglia()
	{
	}
	
	public Famiglia(Famiglia famiglia)
	{
		this.setId(famiglia.getId());
		this.setCdg(famiglia.getCdg());
		this.setNomeReferente(famiglia.getNomeReferente());
		this.setCognomeReferente(famiglia.getCognomeReferente());
		this.setNote(famiglia.getNote());
		this.setPassword(famiglia.getPassword());
		this.setStatus(famiglia.getStatus());
		this.setAssenteAl(famiglia.getAssenteAl());
		this.setAssenteDal(famiglia.getAssenteDal());
		this.setCreated(famiglia.getCreated());
		this.setCreator(famiglia.getCreator());
		this.setModified(famiglia.getModified());
		this.setModifier(famiglia.getModifier());
		this.setLabelValue(famiglia.getNomeReferente() + " " + famiglia.getCognomeReferente());
	}

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cdg == null) ? 0 : cdg.hashCode());
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((status == null) ? 0 : status.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj)
	{
		if(obj instanceof Famiglia)
		{
			Famiglia an = (Famiglia) obj;
			return an.getCdg().equalsIgnoreCase(this.getCdg()) && an.getPassword().equalsIgnoreCase(this.getPassword())
					&& an.getStatus().equals(this.getStatus());
		}
		else
			return false;
	}

	/**
	 * @return a <code>String</code> representation of this object.
	 */
	@Override
	public String toString()
	{
		final String TAB = "    ";

		StringBuilder retValue = new StringBuilder();

		retValue.append(super.toString()).append(TAB).append("id = ").append(this.getId())
				.append(TAB).append("cdg = ").append(this.getCdg()).append(TAB).append("nomeReferente = ")
				.append(this.getNomeReferente()).append(TAB).append("cognomeReferente = ")
				.append(this.getCognomeReferente())
				.append("assenteAl = ").append(this.getAssenteAl()).append(TAB).append("assenteDal = ")
				.append(this.getAssenteDal()).append(TAB).append("note = ").append(this.getNote()).append(TAB)
				.append("status = ").append(this.getStatus()).append(TAB).append("created = ")
				.append(this.getCreated()).append(TAB).append("creator = ").append(this.getCreator()).append(TAB)
				.append("modified = ").append(this.getModified()).append(TAB).append("modifier = ")
				.append(this.getModifier()).append(TAB).append("enabled = ").append(this.isEnabled()).append(TAB)
				.append("authorizationRole = ").append(this.getAuthorizationRole());

		return retValue.toString();
	}

	/**
	 * Clone method
	 * 
	 */
	@Override
	public Famiglia clone()
	{
		Famiglia clone = new Famiglia();

		clone.setId(this.getId());
		clone.setNomeReferente(this.getNomeReferente());
		clone.setCognomeReferente(this.getCognomeReferente());
		clone.setNote(this.getNote());
		clone.setPassword(this.getPassword());
		clone.setStatus(this.getStatus());
		clone.setAssenteAl(this.getAssenteAl());
		clone.setAssenteDal(this.getAssenteDal());
		clone.setCreated(this.getCreated());
		clone.setCreator(this.getCreator());
		clone.setModified(this.getModified());
		clone.setModifier(this.getModifier());
		
		clone.setLabelValue(this.getNomeReferente() + " " + this.getCognomeReferente());

		return clone;
	}

	public long getId()
	{
		return id;
	}

	public void setId(long id)
	{
		this.id = id;
	}

	public String getCdg()
	{
		return cdg;
	}

	public void setCdg(String cdg)
	{
		this.cdg = cdg;
	}

	// TODO da implementare correttamente...
	public Collection<GrantedAuthority> getAuthorities()
	{
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		authorities.add(new GrantedAuthorityImpl(this.getAuthorizationRole()));
		return authorities;
	}

	public boolean isAccountNonExpired()
	{
		if(isEnabled())
		{
			return true;
		}

		return false;
	}

	public boolean isAccountNonLocked()
	{
		if(isEnabled())
		{
			return true;
		}

		return false;
	}

	@Override
	public boolean isCredentialsNonExpired()
	{
		if(isEnabled())
		{
			return true;
		}

		return false;
	}

	public String getPassword()
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

	public String getCognomeReferente()
	{
		return cognomeReferente;
	}

	public void setCognomeReferente(String cognomeReferente)
	{
		this.cognomeReferente = cognomeReferente;
	}

	public String getNomeReferente()
	{
		return nomeReferente;
	}

	public void setNomeReferente(String nomeReferente)
	{
		this.nomeReferente = nomeReferente;
	}

	public String getNote()
	{
		return note;
	}

	public void setNote(String note)
	{
		this.note = note;
	}

	public Date getAssenteDal()
	{
		return assenteDal;
	}

	public void setAssenteDal(Date assenteDal)
	{
		this.assenteDal = assenteDal;
	}

	public Date getAssenteAl()
	{
		return assenteAl;
	}

	public void setAssenteAl(Date assenteAl)
	{
		this.assenteAl = assenteAl;
	}

	public StatoFamiglia getStatus()
	{
		return status;
	}

	public void setStatus(StatoFamiglia status)
	{
		this.status = status;
	}

	public Gruppo getGruppo()
	{
		return gruppo;
	}

	public void setGruppo(Gruppo gruppo)
	{
		this.gruppo = gruppo;
	}

	public boolean isEnabled()
	{
		return enabled;
	}

	public void setEnabled(boolean enabled)
	{
		this.enabled = enabled;
	}

	public String getAuthorizationRole()
	{
		return authorizationRole;
	}

	public void setAuthorizationRole(String authorizationRole)
	{
		this.authorizationRole = authorizationRole;
	}

	@Override
	public String getUsername()
	{
		return getCdg();
	}

	public String getLabelValue()
	{
		return labelValue;
	}

	public void setLabelValue(String labelValue)
	{
		this.labelValue = labelValue;
	}

}
